package cn.csc.module.product.service.category;

import cn.csc.framework.common.pojo.PageResult;
import cn.csc.module.product.api.category.dto.CategoryRespDTO;
import cn.csc.module.product.controller.admin.category.vo.CategoryCreateReqVO;
import cn.csc.module.product.controller.admin.category.vo.CategoryExportReqVO;
import cn.csc.module.product.controller.admin.category.vo.CategoryPageReqVO;
import cn.csc.module.product.controller.admin.category.vo.CategoryUpdateReqVO;
import cn.csc.module.product.controller.admin.spu.vo.SpuPageReqVO;
import cn.csc.module.product.controller.app.category.vo.AppCategoryProductRespVO;
import cn.csc.module.product.controller.app.category.vo.AppCategorySearchReqVO;
import cn.csc.module.product.convert.category.CategoryConvert;
import cn.csc.module.product.dal.dataobject.category.CategoryDO;
import cn.csc.module.product.dal.dataobject.spu.SpuDO;
import cn.csc.module.product.dal.mysql.category.CategoryMapper;
import cn.csc.module.product.dal.mysql.spu.SpuMapper;
import cn.csc.module.product.enums.Constant;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

import static cn.csc.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.csc.module.product.enums.ErrorCodeConstants.*;

/**
 * 分类信息 Service 实现类
 *
 * @author liuchuang
 */
@Slf4j
@Service
@Validated
public class CategoryServiceImpl implements CategoryService {

    @Resource
    private CategoryMapper categoryMapper;
    @Resource
    private SpuMapper spuMapper;

    @Transactional
    @Override
    public BigInteger createCategory(CategoryCreateReqVO createReqVO) {
        // 插入
        CategoryDO category = CategoryConvert.INSTANCE.convert(createReqVO);
        categoryMapper.insert(category);
        if (category.getStatus() == 1 && category.getParentId().compareTo(BigInteger.ZERO) > 0)
            categoryMapper.updateItemNum(category.getParentId(), "+1");

        // 返回
        return category.getId();
    }

    @Transactional
    @Override
    public void updateCategory(CategoryUpdateReqVO updateReqVO) {
        // 校验存在
        CategoryDO categoryDO = categoryMapper.selectById(updateReqVO.getId());
        if (categoryDO == null) {
            throw exception(CATEGORY_NOT_EXISTS);
        }

        if(categoryDO.getProductNum() > 0 && !categoryDO.getName().equals(updateReqVO.getName()))
              throw exception(CATEGORY__UPDATE_PRODUCT);

        if(updateReqVO.getTypeLabel() != null  && updateReqVO.getTypeLabel() != 0 ){
             if(categoryDO.getProductNum().intValue() < 3)
                   throw  exception(CATEGORY__MUCH_PRODUCT);
        }

        if(updateReqVO.getMarkLabel() != null && updateReqVO.getMarkLabel() != 0){
            if(categoryDO.getProductNum().intValue() < 1)
                throw  exception(CATEGORY__MUCH_PRODUCT);
        }

        // 更新
        CategoryDO updateObj = CategoryConvert.INSTANCE.convert(updateReqVO);

        if (categoryDO.getProductNum() > 0 && updateObj.getStatus() == 0)
             throw exception(CATEGORY__DISPLAY_PRODUCT);

        if(updateReqVO.getStatus() != categoryDO.getStatus()){
            if(updateObj.getStatus() == 0) {
                if (categoryDO.getLevel() == 1) {
                    updateObj.setItemNum(0);
                    categoryMapper.updateByParentId(updateObj);
                    categoryMapper.updateByItem(updateObj);
                } else if (categoryDO.getLevel() == 2) {
                    updateObj.setItemNum(0);
                    categoryMapper.updateByItem(updateObj);
                }
            }
        }
        categoryMapper.updateById(updateObj);
        if (updateReqVO.getStatus() == 0 && categoryDO.getStatus() == 1
                && updateReqVO.getParentId().compareTo(BigInteger.ZERO) > 0
                && categoryDO.getItemNum().intValue() > 0)
            categoryMapper.updateItemNum(updateReqVO.getParentId(), "-1");
        else if (updateReqVO.getStatus() == 1 && categoryDO.getStatus() == 0)
            categoryMapper.updateItemNum(updateReqVO.getParentId(), "+1");
    }

    @Transactional
    @Override
    public void deleteCategory(BigInteger id) {
        // 校验存在
        CategoryDO categoryDO = categoryMapper.selectById(id);
        if (categoryDO == null)
            throw exception(CATEGORY_NOT_EXISTS);
        if (categoryDO.getProductNum() > 0)
            throw exception(CATEGORY__EXISTS_PRODUCT);

        if (categoryDO.getLevel() == 1) {
            categoryMapper.delItem(categoryDO);
            categoryDO.setLevel(2);
            categoryMapper.delItem(categoryDO);
        } else if (categoryDO.getLevel() == 2) {
            categoryMapper.delItem(categoryDO);
        }
        // 删除
        categoryMapper.deleteById(id);
        if (!categoryDO.getParentId().toString().equals("0"))
            categoryMapper.updateItemNum(categoryDO.getParentId(), "-1");
    }

    private void validateCategoryExists(BigInteger id) {
        if (categoryMapper.selectById(id) == null) {
            throw exception(CATEGORY_NOT_EXISTS);
        }
    }

    @Override
    public CategoryDO getCategory(BigInteger id) {
        return categoryMapper.selectById(id);
    }

    @Override
    public void getPathNames(List<CategoryDO> categorys) {
        if (CollUtil.isEmpty(categorys)) {
            return;
        }
        // 获取分类的所有上级分类id集合
        Set<BigInteger> paths = new HashSet<>();
        for (CategoryDO category : categorys) {
            if (Objects.isNull(category) || StrUtil.isBlank(category.getPath())) {
                continue;
            }
            String[] parentIds = category.getPath().split(Constant.CATEGORY_INTERVAL);
            for (String parentId : parentIds) {
                paths.add(new BigInteger(parentId));
            }
        }
        if (CollUtil.isEmpty(paths)) {
            return;
        }

        // 获取所有上级分类id列表
        List<CategoryDO> listByCategoryIds = categoryMapper.getListByCategoryIds(paths);
        Map<BigInteger, CategoryDO> categoryMap = listByCategoryIds.stream().collect(Collectors.toMap(CategoryDO::getId, c -> c));

        // 获取每个分类的上级分类名称集合
        for (CategoryDO category : categorys) {
            if (StrUtil.isBlank(category.getPath())) {
                continue;
            }
            String[] parentIdArray = category.getPath().split(Constant.CATEGORY_INTERVAL);
            category.setPathNames(new ArrayList<>());
            for (int i = 0; i < parentIdArray.length; i++) {
                String pathName = categoryMap.get(new BigInteger(parentIdArray[i])).getName();
                category.getPathNames().add(pathName);
            }
        }
    }

    @Override
    public List<CategoryDO> getCategoryList(Collection<BigInteger> ids) {
        return categoryMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<CategoryDO> getCategoryPage(CategoryPageReqVO pageReqVO) {
        return categoryMapper.selectPage(pageReqVO);
    }

    @Override
    public List<CategoryDO> getCategoryList(CategoryExportReqVO exportReqVO) {
        return categoryMapper.selectList(exportReqVO);
    }

    @Override
    public List<BigInteger> listCategoryId(BigInteger shopId, BigInteger parentId) {
        return categoryMapper.listCategoryId(shopId, parentId);
    }

    @Override
    public List<CategoryDO> listByParenId(CategoryCreateReqVO reqVO) {
        return categoryMapper.selectList1(reqVO);
    }

    @Override
//    @Cacheable(cacheNames = ProductCacheNames.CATEGORY_LIST_BY_PARENT_ID_AND_SHOP_ID, key = "#shopId + ':' + #parentId")
    public List<CategoryRespDTO> listByShopIdAndParenId(BigInteger shopId, BigInteger parentId) {
        List<CategoryDO> list = categoryMapper.listByShopIdAndParenId(shopId, parentId);
        return CategoryConvert.INSTANCE.convertList03(list);
    }

    @Override
    public List<CategoryRespDTO> listByShopIdAndLevel(BigInteger shopId, Integer level) {
        List<CategoryDO> list = categoryMapper.listByShopIdAndLevel(shopId, level);
        return CategoryConvert.INSTANCE.convertList03(list);
    }

    @Override
    public List<CategoryRespDTO> listByShopIdAndProduct(BigInteger shopId) {
        SpuPageReqVO reqVO = new SpuPageReqVO();
        reqVO.setShopId(shopId);
        reqVO.setVerifyStatus(10);
        List<SpuDO> list = spuMapper.selectGroupByList(reqVO);
        if (list != null && !list.isEmpty()) {
            Set<BigInteger> ids = list.stream().map(SpuDO::getCategoryId).collect(Collectors.toSet());
            if(ids != null && !ids.isEmpty()) {
                List<CategoryDO> dlist = categoryMapper.getListByCategoryIds(ids);
                return CategoryConvert.INSTANCE.convertList03(dlist);
            }
        }
        return null;
    }

    @Override
    public List<CategoryRespDTO> recommendList() {
        List<CategoryDO> list = categoryMapper.recommendList();
        return CategoryConvert.INSTANCE.convertList03(list);
    }

    @Override
    public List<CategoryRespDTO> topItemList(BigInteger id) {
        List<CategoryDO> list = categoryMapper.topItemList(id);
        return CategoryConvert.INSTANCE.convertList03(list);
    }

    @Override
    public List<CategoryRespDTO> selectCategoryByLevel(AppCategorySearchReqVO reqVO) {
        List<CategoryDO> list = categoryMapper.selectCategoryByLevel(reqVO);
        Map<BigInteger,List<CategoryDO>> cateMap = list.stream().collect(Collectors.groupingBy(CategoryDO::getParentId));
        List<CategoryDO> filterList = list.stream().filter(s->s.getLevel() == 2).collect(Collectors.toList());
        filterList.forEach(e->e.setCategories(cateMap.get(e.getId())));
        log.info("===得出===={}",filterList);
        return CategoryConvert.INSTANCE.convertList03(filterList);
    }

    @Override
    public List<CategoryRespDTO> markLable(CategoryCreateReqVO categoryCreateReqVO) {
        List<CategoryDO> list = categoryMapper.markLable(categoryCreateReqVO);
        return CategoryConvert.INSTANCE.convertList03(list);
    }

    @Override
    public AppCategoryProductRespVO geCategoryById(AppCategorySearchReqVO reqVO) {
        //获取二级类目
        CategoryDO categoryDO = categoryMapper.selectById(reqVO.getCategoryId());
        if(categoryDO == null)
             throw exception(CATEGORY_NOT_EXISTS);

        //获取二级类目下的三级类目
        AppCategoryProductRespVO  respVO = new AppCategoryProductRespVO();
        respVO.setId(categoryDO.getId());
        respVO.setName(categoryDO.getName());
        respVO.setBannerUrl(categoryDO.getBannerUrl());
        List<CategoryDO> list = categoryMapper.selectCategoryByLevel(reqVO);
        List<AppCategoryProductRespVO> item = CategoryConvert.INSTANCE.convertList06(list);
        respVO.setCategorys(item);
        return respVO;
    }
}
